package com.wmh.baseservice.merchant.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wmh.baseservice.common.annotation.parameterverify.ParameterVerify;
import com.wmh.baseservice.common.redis.config.RedisConfig;
import com.wmh.baseservice.common.redis.utils.RedisUtil;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.utils.encrypt.Base64Util;
import com.wmh.baseservice.common.utils.encrypt.RSAUtil;
import com.wmh.baseservice.common.utils.page.pojo.PageInfo;
import com.wmh.baseservice.common.utils.page.pojo.PageResult;
import com.wmh.baseservice.common.utils.page.pojo.PageSortRoles;
import com.wmh.baseservice.common.utils.page.pojo.SortWay;
import com.wmh.baseservice.common.utils.page.util.PageUtil;
import com.wmh.baseservice.common.utils.returnbody.ResultCodeInfo;
import com.wmh.baseservice.common.utils.returnbody.ReturnBody;
import com.wmh.baseservice.merchant.pojo.MerchantInfo;
import com.wmh.baseservice.merchant.pojo.MerchantVegetablePlot;
import com.wmh.baseservice.merchant.service.MerchantInfoService;
import com.wmh.baseservice.merchant.service.MerchantPlotRegionService;
import com.wmh.baseservice.system.pojo.SysChat;
import com.wmh.baseservice.system.pojo.SysMessage;
import com.wmh.baseservice.system.pojo.SysParams;
import com.wmh.baseservice.system.pojo.vo.ChatVo;
import com.wmh.baseservice.system.pojo.vo.MsgListVo;
import com.wmh.baseservice.system.service.SysChatService;
import com.wmh.baseservice.system.service.SysMessageService;
import com.wmh.baseservice.system.service.SysParamsService;
import com.wmh.baseservice.user.pojo.UsGroupGoodsOrder;
import com.wmh.baseservice.user.pojo.UsInfo;
import com.wmh.baseservice.user.pojo.UsVegetableOrder;
import com.wmh.baseservice.user.service.UsGroupGoodsOrderService;
import com.wmh.baseservice.user.service.UsInfoService;
import com.wmh.baseservice.user.service.UsVegetableOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "商家-用户端商家操作接口")
@RestController
@RequestMapping("us/merchantOperation")
@RequiresRoles("merchant")
public class MerchantUsController {

    @Resource
    private UsGroupGoodsOrderService usGroupGoodsOrderService;
    @Resource
    private UsVegetableOrderService usVegetableOrderService;
    @Resource
    private SysMessageService sysMessageService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private MerchantInfoService merchantInfoService;
    @Resource
    private SysChatService sysChatService;
    @Resource
    private UsInfoService usInfoService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private SysParamsService sysParamsService;
    @Resource
    private MerchantPlotRegionService merchantPlotRegionService;

    @ApiOperation("扫码核销")
    @PostMapping("scanQRCodes")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "codeSign", value = "扫码参数", required = true),
    })
    @ParameterVerify(notNull = "codeSign")
    public String scanQRCodes(String codeSign) {
        String orderNum;
        String type;
        try {
            codeSign = RSAUtil.decryptByPrivateKey(codeSign);
            JSONObject object = JSONObject.parseObject(codeSign);
            orderNum = object.getString("orderNum");
            type = object.getString("type");
        } catch (Exception e) {
            return ReturnBody.error("二维码错误，请使用正确的二维码扫描或再次扫码尝试");
        }

        switch (type) {
            //团购
            case "groupGoods":
                UsGroupGoodsOrder usGroupGoodsOrder = usGroupGoodsOrderService.getOneForUpdate(new QueryWrapper<UsGroupGoodsOrder>().eq(UsGroupGoodsOrder.ORDER_NO, orderNum));
                if (!CommUtil.checkNull(usGroupGoodsOrder)) {
                    return ReturnBody.error("拼单订单不存在");
                }
                if (usGroupGoodsOrder.getType() != 0 || usGroupGoodsOrder.getStatus() != 3) {
                    return ReturnBody.error("订单状态错误");
                }
                if (usGroupGoodsOrder.getAfterSaleStatus() != 0) {
                    return ReturnBody.error("该订单已完成售后或正在申请售后中，无法提货");
                }
                //更改订单状态
                usGroupGoodsOrder.setStatus(4);
                usGroupGoodsOrder.setDeliveryTime(new Date());
                usGroupGoodsOrderService.theGoods(usGroupGoodsOrder);
                return ReturnBody.success();
            case "vegetable": {
                UsVegetableOrder usVegetableOrder = usVegetableOrderService.getOneForUpdate(new QueryWrapper<UsVegetableOrder>().eq(UsVegetableOrder.ORDER_NUM, orderNum));
                if (!CommUtil.checkNull(usVegetableOrder)) {
                    return ReturnBody.error("采摘订单不存在");
                }
                if (usVegetableOrder.getType() != 1) {
                    return ReturnBody.error("不是采摘订单");
                }
                if (!CommUtil.checkNull(usVegetableOrder.getHasTake()) || !CommUtil.checkNull(usVegetableOrder.getStatus() != 2)) {
                    return ReturnBody.error("采摘订单状态错误");
                }
                usVegetableOrder.setStatus(2);
                usVegetableOrder.setTakeTime(new Date());
                usVegetableOrderService.confirm(usVegetableOrder);
                return ReturnBody.success();
            }
        }
        return ReturnBody.success();
    }

    @ApiOperation("获取信息")
    @PostMapping("getInfo")
    public String getInfo() {
        Long id = (Long) request.getAttribute("id");
        JSONObject object = new JSONObject(true);
        //未读消息数
        int count = sysMessageService.count(new QueryWrapper<SysMessage>().eq(SysMessage.MERCHANT_ID, id).eq(SysMessage.STATUS, 0));
        object.put("messageCount", count);
        //商家余额
        MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(id);
        if (!CommUtil.checkNull(merchantInfo)) {
            return ReturnBody.error(ResultCodeInfo.PARAM_ERROR);
        }
        object.put("balance", merchantInfo.getBalance());
        if (merchantInfo.getType() == 1) {
            MerchantVegetablePlot status = merchantInfoService.queryPlotStatus(id);
            object.put("plot", status);
        }
        //果蔬订单
        BigDecimal vegetableMoney = usVegetableOrderService.listForUpdate(new QueryWrapper<UsVegetableOrder>().in(UsVegetableOrder.STATUS, 1, 2, 3)).stream().map(UsVegetableOrder::getRealPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        object.put("vegetableMoney", vegetableMoney);
        //团购订单
        BigDecimal groupMoney = usGroupGoodsOrderService.listForUpdate(new QueryWrapper<UsGroupGoodsOrder>().in(UsGroupGoodsOrder.STATUS, 4, 5, 6)).stream().map(UsGroupGoodsOrder::getRealPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        object.put("groupMoney", groupMoney);
        //是否需要缴纳保证金
        SysParams sysParams = sysParamsService.getByIdForUpdate(17L);
        if (CommUtil.checkNull(sysParams)) {
            object.put("hasMargin", sysParams.getValue());
        }
        return ReturnBody.success(object);
    }

    @ApiOperation("自提订单列表")
    @PostMapping("orderList")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "type", value = "1果蔬采摘 2团购自提", required = true),
    })
    @ParameterVerify(notNull = "type")
    public String orderList(PageInfo pageInfo, Integer type) {
        pageInfo.setTimeScreen("create_time");
        pageInfo.setDefaultSort("create_time", SortWay.DESC);
        if (type == 1) {
            //执行分页辅助工具
            PageResult<UsVegetableOrder> pageResult = new PageUtil<UsVegetableOrder>(pageInfo).startPage((page, queryWrapper) -> {
                queryWrapper.eq(UsVegetableOrder.TYPE, 1);
                queryWrapper.isNotNull(UsVegetableOrder.HAS_TAKE);
                usVegetableOrderService.page(page, queryWrapper);
            });
            return ReturnBody.success(pageResult);
        } else {
            //执行分页辅助工具
            PageResult<UsGroupGoodsOrder> pageResult = new PageUtil<UsGroupGoodsOrder>(pageInfo).startPage((page, queryWrapper) -> {
                queryWrapper.eq(UsGroupGoodsOrder.TYPE, 0);
                usGroupGoodsOrderService.page(page, queryWrapper);
            });
            return ReturnBody.success(pageResult);
        }
    }

    @ApiOperation("消息列表")
    @PostMapping("message")
    public String message(PageInfo pageInfo) {
        Long id = (Long) request.getAttribute("id");
        pageInfo.setTimeScreen("create_time");
        pageInfo.setDefaultSort("create_time", SortWay.DESC);
        //执行分页辅助工具
        PageResult<SysMessage> pageResult = new PageUtil<SysMessage>(pageInfo).startPage((page, queryWrapper) -> {
            queryWrapper.eq(SysMessage.MERCHANT_ID, id);
            sysMessageService.page(page, queryWrapper);
        });
        return ReturnBody.success(pageResult);
    }

    @ApiOperation("聊天列表")
    @PostMapping("msgList")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "id", required = false),
    })
    public String list() {
        Long id = (Long) request.getAttribute("id");
        List<MsgListVo> msgListVos = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("type", "merchant");
        map.put("uid", id);
        List<SysChat> sysChats = sysChatService.getList(map);
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        sysChats.forEach(item -> {
            MsgListVo msgListVo = new MsgListVo();
            UsInfo usInfo = usInfoService.getByIdForUpdate(item.getSendType() == 0 ? item.getSendId() : item.getUid());
            if (CommUtil.checkNull(usInfo)) {
                msgListVo.setAvatar(usInfo.getAvatar());
                switch (item.getMsgType()) {
                    case "voice":
                        msgListVo.setContent("<font style='color: #3498db;'>【语音消息】<font/>");
                        break;
                    case "image":
                        msgListVo.setContent("<font style='color: #1abc9c;'>【图片】<font/>");
                        break;
                    case "redEnvelope":
                        msgListVo.setContent("<font style='color: #ff6348;'>【有红包】<font/>");
                        break;
                    default:
                        msgListVo.setContent(item.getContent());
                        break;
                }
                msgListVo.setTime(format.format(item.getCreateTime()));
                msgListVo.setTitle(usInfo.getNick());
                msgListVo.setId(item.getUid());
                msgListVo.setSendId(item.getSendId());
                msgListVo.setType(item.getType());
                msgListVos.add(msgListVo);
            }
        });
        return ReturnBody.success(msgListVos);
    }

    @ApiOperation("获取聊天记录")
    @PostMapping("getMsgList")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "usId", value = "用户id", required = true),
    })
    public String getMsgList(Long usId) {
        Long id = (Long) request.getAttribute("id");
        String suffix = usId + ":" + id;
        String key = RedisConfig.KEY_INFO + "CHAT-" + suffix;

        if (redisUtil.hasKey(key)) {
            List<SysChat> sysChats = (List<SysChat>) redisUtil.get(key);
            //标注已读,定时任务凌晨回写数据库
            sysChats.forEach(item -> item.setStatus(1));
            //处理数据格式
            return ReturnBody.success(conversion(sysChats));
        } else {
            //查询数据库
            List<SysChat> sysChats = sysChatService.listForUpdate(new QueryWrapper<SysChat>().eq(SysChat.SESSION_ID, suffix))
                    .stream().sorted(Comparator.comparing(SysChat::getCreateTime).reversed()).collect(Collectors.toList());
            sysChats.forEach(item -> item.setStatus(1));
            //修改数据库
//            if (!sysChatService.updateBatchById(sysChats)) {
//                throw new ServiceException("回写状态异常");
//            }
            redisUtil.set(key, sysChats);
            return ReturnBody.success(conversion(sysChats));
        }
    }

    private List<ChatVo> conversion(List<SysChat> sysChats) {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        List<ChatVo> chatVoList = new ArrayList<>();
        for (SysChat sysChat : sysChats) {
            ChatVo chatVo = new ChatVo();
            JSONObject object = new JSONObject(true);
            object.put("id", sysChat.getId());
            object.put("type", sysChat.getMsgType());
            object.put("time", format.format(sysChat.getCreateTime()));
            object.put("sendType", sysChat.getType());
            JSONObject infoObj = new JSONObject(true);
            infoObj.put("uid", sysChat.getUid());
            if ("user".equals(sysChat.getType())) {
                UsInfo usInfo = usInfoService.getByIdForUpdate(sysChat.getUid());
                infoObj.put("username", usInfo.getNick());
                infoObj.put("face", usInfo.getAvatar());
            } else if ("merchant".equals(sysChat.getType())) {
                MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(sysChat.getUid());
                infoObj.put("username", merchantInfo.getStoreName());
                infoObj.put("face", merchantInfo.getStoreAvatar());
            }
            object.put("userinfo", infoObj);
            infoObj = new JSONObject(true);
            infoObj.put("text", sysChat.getContent());
            switch (sysChat.getMsgType()) {
                case "image":
                    infoObj.put("w", sysChat.getW());
                    infoObj.put("h", sysChat.getH());
                    break;
                case "voice":
                    infoObj.put("length", sysChat.getLength());
                    break;
                case "redEnvelope":
                    infoObj.put("blessing", sysChat.getContent());
                    infoObj.put("rid", sysChat.getRid());
                    infoObj.put("isReceived", sysChat.getHasReceived() == 1);
                    break;
            }
            object.put("content", infoObj);
            chatVo.setType("user");
            chatVo.setMsg(object);
            chatVoList.add(chatVo);
        }
        return chatVoList;
    }


    @ApiOperation("我的消息")
    @PostMapping("myMessage")
    public String myMessage(PageInfo pageInfo) {
        Long mid = (Long) request.getAttribute("id");
        PageSortRoles pageSortRoles = new PageSortRoles();
        pageSortRoles.putPageSortRoles(SysMessage.STATUS, SysMessage.STATUS, SortWay.ASC);
        pageSortRoles.putPageSortRoles(SysMessage.CREATE_TIME, SysMessage.CREATE_TIME, SortWay.DESC);
        pageInfo.setPageSortRoles(pageSortRoles);
        //执行分页辅助工具
        PageResult<SysMessage> pageResult = new PageUtil<SysMessage>(pageInfo).startPage((page, queryWrapper) -> {
            queryWrapper.eq(SysMessage.MERCHANT_ID, mid);
            queryWrapper.select(SysMessage.TITLE, SysMessage.CONTENT, SysMessage.STATUS, SysMessage.ID, SysMessage.MERCHANT_ID, SysMessage.CREATE_TIME);
            sysMessageService.page(page, queryWrapper);
        });
        return ReturnBody.success(pageResult);
    }

    @ApiOperation("未读消息数")
    @PostMapping("unRead")
    public String unRead() {
        Long mid = (Long) request.getAttribute("id");
        int count = sysMessageService.count(new QueryWrapper<SysMessage>().eq(SysMessage.MERCHANT_ID, mid).eq(SysMessage.STATUS, 0));
        return ReturnBody.success(count);
    }

    @ApiOperation("已读")
    @PostMapping("read")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "id", required = false),
    })
    public String msgList(Long id) {
        Long mid = (Long) request.getAttribute("id");
        UpdateWrapper<SysMessage> updateWrapper = new UpdateWrapper<SysMessage>().set(SysMessage.STATUS, 1).eq(SysMessage.MERCHANT_ID, mid).eq(SysMessage.ID, id);
        if (!sysMessageService.update(updateWrapper)) {
            return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
        }
        return ReturnBody.success();
    }

    @ApiOperation("修改商家信息")
    @PostMapping("updateInfo")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "id", required = false),
    })
    public String updateInfo(String avatar, String name) {
        Long id = (Long) request.getAttribute("id");
        MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(id);
        if (CommUtil.checkNull(avatar)) {
            avatar = Base64Util.generateImage("/goodsM", avatar);
            merchantInfo.setStoreAvatar(avatar);
        }
        if (CommUtil.checkNull(merchantInfo.setStoreName(name))) {
            merchantInfo.setStoreName(name);
        }
        if (!merchantInfoService.updateById(merchantInfo)) {
            return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
        }
        return ReturnBody.success();
    }




}

